<?php

namespace falcon5\inc\Http;

/**
 * Class JsonResponse
 * @package falcon5\inc\Http
 */
class JsonResponse
{
    private $data;
    private $code;
    private $message;
    private $extra;
    private $httpStatus;

    public function __construct($data = null, int $code = 200, string $message = '', $extra = null, int $httpStatus = 200)
    {
        $this->data = $data;
        $this->code = $code;
        $this->message = $message;
        $this->extra = $extra;
        $this->httpStatus = $httpStatus;
    }

    /**
     * Send response
     */
    public function send()
    {
        // Remove any previous headers that might interfere
        if (!headers_sent()) {
            // Clear any previous headers that might be set
            header_remove();
            
            // Set HTTP status code using both methods for maximum compatibility
            http_response_code($this->httpStatus);
            header("HTTP/1.1 {$this->httpStatus} " . $this->getStatusText($this->httpStatus));
            
            // Set content type
            header('Content-Type: application/json');
            
            // Add no-cache headers to prevent caching issues
            header('Cache-Control: no-store, no-cache, must-revalidate, max-age=0');
            header('Pragma: no-cache');
        }
        
        // Output the JSON response
        echo json_encode([
            'code' => $this->code,
            'msg' => $this->message,
            'data' => $this->data,
            'extra' => $this->extra,
            'http_status' => $this->httpStatus, // Include HTTP status in response for debugging
        ]);
        
        if (defined('DOING_AJAX') && DOING_AJAX) {
            wp_die('', '', ['response' => $this->httpStatus]); // Pass status code to wp_die
        }
    }
    
    /**
     * Get status text for HTTP status code
     * 
     * @param int $code HTTP status code
     * @return string Status text
     */
    private function getStatusText(int $code): string
    {
        $texts = [
            200 => 'OK',
            201 => 'Created',
            204 => 'No Content',
            400 => 'Bad Request',
            401 => 'Unauthorized',
            403 => 'Forbidden',
            404 => 'Not Found',
            405 => 'Method Not Allowed',
            500 => 'Internal Server Error',
        ];
        
        return $texts[$code] ?? 'Unknown Status';
    }

    /**
     * Create success response
     * @param mixed $data
     * @return JsonResponse
     */
    public static function success($data = null): JsonResponse
    {
        return new self($data, 1, 'success', null, 200);
    }

    /**
     * Create error response
     * @param int $code Business error code
     * @param string $message Error message
     * @param mixed $extra Additional information
     * @param int $httpStatus HTTP status code, default 400
     * @return JsonResponse
     */
    public static function error(int $code, string $message, $extra = null, int $httpStatus = 400): JsonResponse
    {
        return new self(null, $code, $message, $extra, $httpStatus);
    }
    
    /**
     * Get response data
     * @return mixed
     */
    public function getData()
    {
        return $this->data;
    }
    
    /**
     * Get response code
     * @return int
     */
    public function getCode(): int
    {
        return $this->code;
    }
    
    /**
     * Get response message
     * @return string
     */
    public function getMessage(): string
    {
        return $this->message;
    }
    
    /**
     * Get extra data
     * @return mixed
     */
    public function getExtra()
    {
        return $this->extra;
    }
    
    /**
     * Get HTTP status code
     * @return int
     */
    public function getHttpStatus(): int
    {
        return $this->httpStatus;
    }
    
    /**
     * Set HTTP status code
     * @param int $httpStatus
     * @return $this
     */
    public function setHttpStatus(int $httpStatus): self
    {
        $this->httpStatus = $httpStatus;
        return $this;
    }
} 